package com.dp.server;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;


import com.dp.client.dto.AlmacenBusqueda;
import com.dp.client.dto.AlmacenDTO;
import com.dp.client.dto.CiudadDTO;
import com.dp.client.dto.ClienteDTO;
import com.dp.client.dto.ContinenteDTO;
import com.dp.client.dto.Fecha;
import com.dp.client.dto.PaisDTO;
import com.dp.client.dto.PaqueteDTO;
import com.dp.client.dto.Reportes;
import com.dp.client.servicios.almacenes.IServiciosAlmacen;
import com.dp.client.servicios.clientes.IServiciosCliente;
import com.dp.server.backend.servicios.ServiciosBackend;
import com.dp.client.servicios.simulacion.IServiciosSimulacion;
import com.dp.client.servicios.simulacion.IServiciosSimulacionAsync;
import com.dp.client.util.Alerts;
import com.dp.server.entities.Almacen;
import com.dp.server.entities.Cliente;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class IServiciosAlmacenImpl extends RemoteServiceServlet implements IServiciosAlmacen{
	final private MantenimientoGenerico<Almacen> mantenimientoGenerico= new MantenimientoGenerico("Almacen");
	@Override
	public boolean registrarAlmacen(AlmacenDTO almacenDTO) {
		Almacen almacen = new Almacen(almacenDTO);
		return mantenimientoGenerico.registra(almacen) != null;
	}
	
	public boolean registrarAlmacen2(Almacen almacen) {
		return mantenimientoGenerico.registra(almacen) != null;
	}
	
	public Almacen obtenerId(int id)
	{
		List<Almacen> lista = mantenimientoGenerico.list();
		for(int i=0;i<lista.size();i++)
			if(lista.get(i).getCiudadId()==id)
				return lista.get(i);
		return null;
	}

	@Override
	public List<AlmacenDTO> listAlmacenes() {
		List<Almacen> lista=mantenimientoGenerico.list();
		ArrayList<AlmacenDTO> result = new ArrayList<AlmacenDTO>();
		for(Almacen a : lista){
			CiudadDTO ciudad=(new IServiciosGeograficosImpl()).getCiudad(a.getCiudadId()); 
			
				result.add(new AlmacenDTO(a.getId(),a.getCapacidadMaxima(),a.getLatitud(),a.getLongitud(),a.getDescripcion(),ciudad, 
						0));
			
		}
		return result;	
	}

	@Override
	public boolean eliminarAlmacen(int almacenId) {
		return mantenimientoGenerico.eliminar(almacenId);
	}

	@Override
	public List<AlmacenDTO> buscarAlmacen(AlmacenBusqueda almacenBusqueda) {
		//EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("some_name_you_choose");
		EntityManagerFactory entityManagerFactory=MantenimientoGenerico.entityManagerFactory;
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		
		List <CiudadDTO> ciudades=null;
		String query = "from Almacen where ";
		query+=" descripcion like '%"+almacenBusqueda.getDescripcion()+"%' ";
		if (almacenBusqueda.getCiudadId()>0){
			query+=" and ciudadId="+almacenBusqueda.getCiudadId()+" ";
		}
		else if (almacenBusqueda.getPaisId()>0){
			ciudades=(new IServiciosGeograficosImpl()).listCiudades(-1,almacenBusqueda.getPaisId()+"");
		}
		else if (almacenBusqueda.getContinenteId()>0){
			List <PaisDTO> paises=(new IServiciosGeograficosImpl()).listPaises(-1,almacenBusqueda.getContinenteId()+"");
			for (PaisDTO p:paises){
				if (ciudades==null)
					ciudades=(new IServiciosGeograficosImpl()).listCiudades(-1,p.getId()+"");
				else 
					ciudades.addAll((new IServiciosGeograficosImpl()).listCiudades(-1,p.getId()+""));
			}
		}
		if ( almacenBusqueda.getCapacidadMinima()>0){
			query+=" and capacidadMaxima>="+almacenBusqueda.getCapacidadMinima()+" ";
		}
		if ( almacenBusqueda.getCapacidadMaxima()>0){
			query+=" and capacidadMaxima<="+almacenBusqueda.getCapacidadMaxima()+" ";
		}
		List <Almacen> lista=entityManager.createQuery(query).getResultList();
		entityManager.close();
		
		ArrayList <AlmacenDTO> almacenes=new ArrayList <AlmacenDTO>();
		for( Almacen a: lista ){
			boolean agregar=false;
			if ( ciudades!=null )
				for( CiudadDTO c: ciudades ){
					if( a.getCiudadId() == c.getId() ){
						agregar = true;
						break;
					}
				}
			if ( ciudades!=null && !agregar) continue;
			CiudadDTO ciudad= ( new IServiciosGeograficosImpl() ).getCiudad( a.getCiudadId() ); 
				almacenes.add(new AlmacenDTO(a.getId(),a.getCapacidadMaxima(),a.getLatitud(),a.getLongitud(),a.getDescripcion(),ciudad, 
						0));
			
		}
		return almacenes;
	}

	public AlmacenDTO getAlmacen(int almacenId) {
		//System.out.println(" id de servicio "+almacenId);
		Almacen almacen=mantenimientoGenerico.buscarID(almacenId);
		CiudadDTO ciudad=(new IServiciosGeograficosImpl()).getCiudad(almacen.getCiudadId()); 
		AlmacenDTO almacenDTO = new AlmacenDTO();
			almacenDTO = new AlmacenDTO(almacen.getId(),almacen.getCapacidadMaxima(),almacen.getLatitud(),almacen.getLongitud(),almacen.getDescripcion(),ciudad,
					0);
		return almacenDTO;
	}

	@Override
	public AlmacenDTO getAlmacenByCiudad(String ciudadId){
		for (AlmacenDTO a : listAlmacenes()){
			if ( a.getCiudad().getId() == Integer.parseInt(ciudadId) )
				return a;
		}
		return null;
	}

	@Override
	public String enviarCorreo(ClienteDTO emisor, ClienteDTO receptor,
			PaqueteDTO paquete) {
		IServiciosEnviarCorreo serviciosEnviarCorreo = new IServiciosEnviarCorreo();
		serviciosEnviarCorreo.RegistrarPaquete(emisor, receptor, paquete);
		return null;
	}

	@Override
	public List<AlmacenDTO> listAlmacenesConDatosEnTiempoReal() {
		List<Almacen> lista=mantenimientoGenerico.list();
		ArrayList<AlmacenDTO> result = new ArrayList<AlmacenDTO>();
		for(Almacen a : lista){
			CiudadDTO ciudad=(new IServiciosGeograficosImpl()).getCiudad(a.getCiudadId()); 
			try {
				result.add(new AlmacenDTO(a.getId(),a.getCapacidadMaxima(),a.getLatitud(),a.getLongitud(),a.getDescripcion(),ciudad, 
						new ServiciosBackend().getCapacidadDisponibleAlmacenEnFecha(a.getDescripcion(), Fecha.getFechaFromDate(new Date()))));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return result;
	}
	
	@Override
	public Reportes getReporteAlmacen(java.util.Date fechaMin,java.util.Date fechaMax){
		Reportes r=new Reportes();
		ArrayList <String> px=new ArrayList<>();
		ArrayList <Integer> pyH=new ArrayList<>();
		ArrayList <Integer> pyL=new ArrayList<>();
		List <AlmacenDTO> almacenes=listAlmacenes();
		for (AlmacenDTO a : almacenes){
			int capacidadDisponible=new IServiciosSimulacionImpl().getCapacidadDisponibleAlmacenEnFecha(a.getDescripcion(), new java.util.Date());
			px.add(a.getDescripcion());
			pyH.add(capacidadDisponible);
			pyL.add(a.getCapacidadMaxima()-capacidadDisponible);
		}
		
		r.pointsX=px;
		r.pointsYHigh=pyH;
		r.pointsYLow=pyL;
		/*
		ArrayList <String> px=new ArrayList<>();
		px.add("campo");px.add("campo2");px.add("campo3");
		pyH.add(4);pyH.add(5);pyH.add(7);
		pyL.add(6);pyL.add(3);pyL.add(2);
		*/
		return r;
	}
}
